pull: Ensure worker queue finishes if we unhold an empty queue too
authorColin Walters <walters@verbum.org>
Fri, 5 Oct 2012 00:32:14 +0000 (20:32 -0400)
committerColin Walters <walters@verbum.org>
Fri, 5 Oct 2012 00:32:14 +0000 (20:32 -0400)
src/libotutil/ot-worker-queue.c

index 797c1686ebe3b065eaf0af6c545a9d675a1e9c67..8bf71bee4a291fc55adb6435bec8b0ec81aeee9e 100644 (file)
@@ -79,10 +79,31 @@ ot_worker_queue_hold (OtWorkerQueue  *queue)
   g_atomic_int_inc (&queue->holds);
 }
 
+static gboolean
+invoke_idle_callback (gpointer user_data)
+{
+  OtWorkerQueue *queue = user_data;
+  queue->idle_callback (queue->idle_data);
+  return FALSE;
+}
+
 void
 ot_worker_queue_release (OtWorkerQueue  *queue)
 {
-  g_atomic_int_add (&queue->holds, -1);
+  if (!g_atomic_int_dec_and_test (&queue->holds))
+    return;
+
+  g_mutex_lock (&queue->mutex);
+
+  if (!g_queue_peek_tail_link (&queue->queue))
+    {
+      if (queue->idle_callback)
+        g_main_context_invoke (queue->idle_context,
+                               invoke_idle_callback,
+                               queue);
+    }
+
+  g_mutex_unlock (&queue->mutex);
 }
 
 void
@@ -95,14 +116,6 @@ ot_worker_queue_push (OtWorkerQueue *queue,
   g_mutex_unlock (&queue->mutex);
 }
 
-static gboolean
-invoke_idle_callback (gpointer user_data)
-{
-  OtWorkerQueue *queue = user_data;
-  queue->idle_callback (queue->idle_data);
-  return FALSE;
-}
-
 static gpointer
 ot_worker_queue_thread_main (gpointer user_data)
 {